<?php

declare(strict_types=1);

namespace JfbQueue;

use JfbQueue\Driver\DriverInterface;
use Hyperf\Context\ApplicationContext;
use Hyperf\Contract\ConfigInterface;
use Hyperf\Process\Annotation\Process;
use Hyperf\Process\ProcessManager;
use Hyperf\Redis\RedisFactory;
use Hyperfx\Framework\Exception\AppException;
use Hyperfx\Framework\Logger\Logx;
use Hyperfx\Utils\AppEnvUtil;
use Hyperfx\Utils\RunModeUtil;
use Psr\Container\ContainerInterface;
use Hyperf\Process\AbstractProcess;
use Swoole\Exception;


class DriverFactory  {


    protected array $config;

    private $map = [];

    public function __construct(ContainerInterface $container)
    {
        $objConfig = $container->get(ConfigInterface::class);
        $this->config = $objConfig->get('async_queue_x', []);
    }

    public function get(string $queue = 'default'): DriverInterface
    {
        if (!isset($this->map[$queue])) {
            $config = $this->getConfigByQueue($queue);

            $driverClass = $config['driver'];
            if (! class_exists($driverClass)) {
                throw new Exception(sprintf('[Error] class %s is invalid.', $driverClass));
            }

            $driver = make($driverClass, ['config' => $config]);
            if (! $driver instanceof DriverInterface) {
                throw new Exception(sprintf('[Error] class %s is not instanceof %s.', $driverClass, DriverInterface::class));
            }
            $this->map[$queue] = $driver;
        }

        return $this->map[$queue];
    }

    public function getConfigByQueue($queue): array {
        $config = $this->config['mapping'][$queue] ?? [];
        if (empty($config)) {
            throw new Exception(sprintf('[Error] async_queue_x %s config is not exist', $queue));
        }
        return $config;
    }

    public function getAllQueueNames(): array {
        return array_keys($this->config['mapping']);
    }

    public function isEnabledReload(): bool {
        if (false === ($this->config['enabled'] ?? false)) {
            return false;
        }
        if (empty($this->config['mapping'])) {
            return false;
        }
        foreach ($this->config['mapping'] as $item) {
            // 有一个是开启的, 就返回true,默认为开启
            if ($item['is_reload'] ?? true) {
                return true;
            }
        }
        return true;
    }

    /**
     * 获取可以重载的队列
     */
    public function getCanReloadQueues(): array {
        if (!$this->isEnabledReload()) {
            return [];
        }
        $queues = [];
        foreach ($this->config['mapping'] as $queue => $item) {
            // 有一个是开启的, 就返回true,默认为开启
            if ($item['is_reload'] ?? true) {
                $queues[] = $queue;
            }
        }
        return $queues;
    }

    public function getReloadTime() {
        return $this->config['reload_time'] ?? 5;
    }
}